package com.atelier.plugin.database.util;

import com.atelier.plugin.database.domain.*;
import com.atelier.plugin.database.driver.DatabaseDriverManager;
import com.atelier.plugin.database.ui.DataBaseValid;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.openapi.extensions.PluginId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class ConnectionUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionUtil.class);

    private static ConnectionUtil instance;

    private   Connection connection;
    private DatabaseConnectionInfo info;

    private ConnectionUtil(DatabaseConnectionInfo info) throws SQLException {

            String jdbcUrl = createJdbcUrl(info);
            connection = DriverManager.getConnection(jdbcUrl, info.getUsername(),info.getPassword());
            this.info=info;

    }
    // 获取单例实例的方法
    public static ConnectionUtil getInstance(DatabaseConnectionInfo info) throws SQLException {
        if (instance == null) {
            instance = new ConnectionUtil(info);
        }
        String jdbcUrl = instance.createJdbcUrl(info);
        Properties properties = new Properties();
        properties.put("user", info.getUsername());
        properties.put("password", info.getPassword());
        properties.put("remarksReporting", "true");// 注意这里不可或缺
        try {
            instance.setConnection(DriverManager.getConnection(jdbcUrl, properties));

        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        instance.setInfo(info);
        return instance;
    }
    public boolean testConnection() {
        return connection != null;
    }

    public List<TableInfo> fetchDatabaseInfo() throws SQLException {
       //从conn中获取数据库的元数据
        DatabaseMetaData databaseMetaData = connection.getMetaData();
        //库信息
        //连接的库名
        System.out.println(connection.getCatalog());
        //数据库类型 MYSQL ORACLE
        System.out.println(databaseMetaData.getDatabaseProductName());
        //数据库版本号 8.0.15
        System.out.println(databaseMetaData.getDatabaseProductVersion());
        this.getInfo().setDriverVersion(databaseMetaData.getDatabaseProductVersion());
        //数据库大版本 8
        System.out.println(databaseMetaData.getDatabaseMajorVersion());
        //jdbc连接的url
        System.out.println(databaseMetaData.getURL());
        List<TableInfo> tableInfoList = new ArrayList<>();
        if (connection == null) {
            System.out.println("Not connected to the database.");
            return tableInfoList;
        }

        try {
            DatabaseMetaData metaData = connection.getMetaData();
            ResultSet tables = null;
            System.out.println(metaData.getUserName());

            if (this.info.getDatabaseType().equals(DatabaseType.MYSQL)) {
                tables = metaData.getTables(this.info.getDatabaseName(), null, null, new String[]{"TABLE"});
            } else if (this.info.getDatabaseType().equals(DatabaseType.ORACLE)) {
                String username = this.info.getUsername();
                System.out.println(username);
                tables = metaData.getTables(connection.getCatalog(),metaData.getUserName() , null, new String[]{"TABLE"});
            }
            while (tables.next()) {
                String tableName = tables.getString("TABLE_NAME");
                String tableRemarks = tables.getString("REMARKS");
                String tableRemarks1 = tables.getString("REMARKS");
                LOGGER.info("表名:=="+tableName+"   表注释=="+tableRemarks);
                LOGGER.info("表名:=="+tableName+"   表注释++"+tableRemarks1);
                TableInfo tableInfo = new TableInfo(tableName);
                tableInfo.setRemark(tableRemarks);
                ResultSet columns = metaData.getColumns(connection.getCatalog(), metaData.getUserName(), tableName, null);
                while (columns.next()) {
                    String columnName = columns.getString("COLUMN_NAME");
                    String columnType = columns.getString("TYPE_NAME");
                    String remarks = columns.getString("REMARKS");
                    String typeName = columns.getString("TYPE_NAME");//字段类型
                    String columnDef = columns.getString("COLUMN_DEF");//默认值
                    int columnSize = columns.getInt("COLUMN_SIZE");
                    String decimalDigits = columns.getString("DECIMAL_DIGITS");//长度
                    String ordinalPosition = columns.getString("ORDINAL_POSITION");//字段位置
                    String isAutoincrement = columns.getString("IS_AUTOINCREMENT");//是否自增


                    boolean isPrimaryKey = false;
                    ResultSet rs2 = connection.getMetaData().getPrimaryKeys(connection.getCatalog(), null, tableName);
                    while (rs2.next()){
                        if (columnName.equals(rs2.getString("COLUMN_NAME"))) {
                            isPrimaryKey = true;
                            break;
                        }
                    }
                    tableInfo.addColumnInfo(new ColumnInfo(columnName, columnType, columnSize,remarks,isPrimaryKey,
                            typeName,columnDef,isAutoincrement,ordinalPosition,decimalDigits));
                    System.out.println(columns.getString("TABLE_NAME")//表名
                            +"-"+columns.getString("column_name")//字段名
                            +"-"+columns.getString("TYPE_NAME")//字段类型
                            +"-"+columns.getString("DATA_TYPE")//字段类型
                            +"-"+columns.getString("COLUMN_SIZE")//长度
                            +"-"+columns.getString("DECIMAL_DIGITS")//长度
                           // +"-"+columns.getString("COLUMN_DEF")//默认值
                            +"-字段注释"+columns.getString("REMARKS")//注释
                            +"-"+columns.getString("ORDINAL_POSITION")//字段位置
                            +"-"+columns.getString("IS_AUTOINCREMENT"));//是否自增
                }
//获取表主键

                tableInfoList.add(tableInfo);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return tableInfoList;
    }

    public  static  void closeConnection() {
        if(instance !=null) {
            Connection connection = instance.getConnection();
            try {
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                instance.setConnection(null);
            }
        }
    }

    private String createJdbcUrl(DatabaseConnectionInfo info) {
        String jdbcUrl = null;
        String driverDir = PluginManager.getPlugin(PluginId.getId("com.hyway.plugin.atelier")).getPluginPath().toString()+"\\lib\\";
        try {
                DatabaseDriverManager driverManager = DatabaseDriverManager.getInstance();
                List<Driver> drivers = driverManager.loadDriverClassesWithProgressBar(driverDir + info.getDatabaseType().getConnectorJarFile());
                Driver mySqlDriver = drivers.get(0); // 假设 MySQL 驱动是列表中的第一个元素
                // 注册驱动程
                DriverManager.registerDriver(mySqlDriver);
                DriverManager.getDrivers();
                jdbcUrl = String.format(info.getDatabaseType().getConnectionUrlPattern(),
                 DataBaseValid.isValidHost(info.getHost())? "127.0.0.1" : info.getHost(), DataBaseValid.isValidPort(info.getPort()) ? info.getPort() :info.getDatabaseType().getDefaultPort() ,info.getDatabaseName(),"utf8");
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return jdbcUrl;
    }

    public DatabaseConnectionInfo getInfo() {
        return info;
    }

    public Connection getConnection() {
        return connection;
    }

    public void setConnection(Connection connection) {
        this.connection = connection;
    }

    public void setInfo(DatabaseConnectionInfo info) {
        this.info = info;
    }
}
